#pragma once

#include "window.h"
#include "input.h"

#define CONFIG_WM_DRAW_CURSOR

#define WM_FIFO_EVENT_LEN 64

#define WM_RENDER_EVENT_NR 1

#define WM_POLL_EVENT_MAX (WM_INPUT_DEVICE_NR + WM_RENDER_EVENT_NR)

typedef struct
{
    NX_List windowList;
    WM_WindowType * windowID[NX_WIN_ID_MAX];
    WM_WindowType base;
    WM_WindowType * cursor;
    NX_Region update;

    WM_WindowType * focused;
    WM_WindowType * hit;
    NX_Bool is_press;
} WM_WindowManager;

void WM_FocusWindow(WM_WindowType * w);
void WM_FocusWindowByTop(void);
void WM_FocusWindowByMouse(int mouse_x, int mouse_y, int code);
void WM_ReleaseMouseOnFocusWindow(int mouse_x, int mouse_y, int code);
void WM_WheelMouseOnFocusWindow(int mouse_x, int mouse_y, NX_WindowEventType type);

NX_WindowID WM_WindowAllocID(WM_WindowType *w);
void WM_WindowFreeID(NX_WindowID id);
WM_WindowType *WM_WindowGetByID(NX_WindowID id);
void WM_SendRenderEvent(WM_WindowRenderEvent e);
void WM_SendKeycode(NX_WindowEventType type, int code);
NX_Error WM_WindowSendEvent(WM_WindowType * w, NX_WindowEvent e);
NX_Error WM_WindowRecvEvent(WM_WindowType * w, NX_WindowEvent *e, NX_Bool isBlock);

void WM_MergeUpdateRegion(NX_Region r);

void WM_RaiseWindow(WM_WindowType * w);
void WM_FlushWindow(void);
void WM_HideWindow(WM_WindowType * w);

NX_U32 WM_GetWidth(void);
NX_U32 WM_GetHeight(void);

NX_Error WM_WindowSystemInit(void);
void WM_WindowSystemExit(void);
